package com.tianlang.security.tool;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;

import com.tianlang.domain.pojo.Authority;
import com.tianlang.util.ClassPathScanManager;

public class AcegiUtil {
	private static Logger LOG = Logger.getLogger(AcegiUtil.class);

	public static void main(String[] args) throws Exception {
		HashMap<String, List<Authority>> ab = getDefaultConfig();
	}

	public static HashMap<String, List<Authority>> getDefaultConfig() throws Exception {
		Set<Class> classes = ClassPathScanManager.getClasses("com.tianlang.web.controller");
		HashMap<String, List<Authority>> root = new HashMap<String, List<Authority>>();
		Class<Acegi> acegi = Acegi.class;
		Class<RequestMapping> rm = RequestMapping.class;
		for (Class<?> _class : classes) {
			Acegi _acegi = _class.getAnnotation(acegi);
			RequestMapping mapping = _class.getAnnotation(rm);
			String[] acegiValues = null;
			String acegiValue = null;
			if (_acegi != null) {
				acegiValues = _acegi.value();
				if (acegiValues.length == 1) {
					acegiValue = acegiValues[0];
				} else if (acegiValues.length == 2) {
					acegiValue = acegiValues[1];
				}
			}
			Method[] methods = _class.getMethods();
			for (Method method : methods) {
				String key = "";
				if (mapping != null) {
					key = mapping.value()[0];
				}
				if (method.isAnnotationPresent(acegi)) {
					if (method.isAnnotationPresent(rm)) {
						key += method.getAnnotation(rm).value()[0];
					}
					String[] acegiMethodValues = method.getAnnotation(acegi).value();
					String[] roles;
					Short isObliged = 0;
					if (acegiMethodValues.length == 3 && (acegiMethodValues[2].equalsIgnoreCase("false")
							|| acegiMethodValues[2].equalsIgnoreCase("true"))) {
						roles = acegiMethodValues[1].split(",");
						if (acegiMethodValues[2].equalsIgnoreCase("false")) {
							isObliged = 0;
						} else {
							isObliged = 1;
						}
						putValue(key, roles, isObliged, acegiMethodValues[0], root);
						continue;
					}
					if (acegiMethodValues.length == 1 && acegiValue != null) {
						roles = acegiValue.split(",");
						putValue(key, roles, isObliged, acegiMethodValues[0], root);
						continue;
					}
					if (acegiMethodValues.length == 2 && acegiValue != null
							&& (acegiMethodValues[1].equalsIgnoreCase("false")
									|| acegiMethodValues[1].equalsIgnoreCase("true"))) {
						roles = acegiValue.split(",");
						if (acegiMethodValues[1].equalsIgnoreCase("false")) {
							isObliged = 0;
						} else {
							isObliged = 1;
						}
						putValue(key, roles, isObliged, acegiMethodValues[0], root);
						continue;
					}
					if (acegiMethodValues.length == 2 && acegiValue != null) {
						roles = acegiMethodValues[1].split(",");
						putValue(key, roles, isObliged, acegiMethodValues[0], root);
						continue;
					}
					throw new Exception("权限配置错误=>>>>>" + key);

				}
			}
		}
		return root;
	}

	/***
	 * 获得资源
	 * 
	 * @return
	 * @throws Exception
	 */
	public static HashMap<String, List<Authority>> getDefaultSecurity() throws Exception {
		Set<Class> classes = ClassPathScanManager.getClasses("com.tianlang.web.controller");
		HashMap<String, List<Authority>> root = new HashMap<String, List<Authority>>();
		Class<Acegi> acegi = Acegi.class;
		Class<RequestMapping> rm = RequestMapping.class;
		for (Class<?> _class : classes) {
			RequestMapping mapping = _class.getAnnotation(rm);
			Acegi _acegi = _class.getAnnotation(acegi);
			String[] acegiValues = null;
			String acegiValue = null;
			String groupName = "基础权限配置";
			if (_acegi != null) {
				acegiValues = _acegi.value();
				if (acegiValues.length == 1) {
					acegiValue = acegiValues[0];
				} else if (acegiValues.length == 2) {
					groupName = acegiValues[0];
					acegiValue = acegiValues[1];
				}
			}
			Method[] methods = _class.getMethods();
			for (Method method : methods) {
				String key = "";
				if (mapping != null) {
					key = mapping.value()[0];
				}
				if (method.isAnnotationPresent(acegi)) {
					if (method.isAnnotationPresent(rm)) {
						key += method.getAnnotation(rm).value()[0];
					}
					String[] acegiMethodValues = method.getAnnotation(acegi).value();
					Short isObliged = 0;
					if (acegiMethodValues.length == 3 && (acegiMethodValues[2].equalsIgnoreCase("false")
							|| acegiMethodValues[2].equalsIgnoreCase("true"))) {
						if (acegiMethodValues[2].equalsIgnoreCase("false")) {
							isObliged = 0;
						} else {
							isObliged = 1;
						}
						resourcesPutvalue(groupName, key, isObliged, acegiMethodValues[0], root);
						continue;
					}
					if (acegiMethodValues.length == 1 && acegiValue != null) {
						resourcesPutvalue(groupName, key, isObliged, acegiMethodValues[0], root);
						continue;
					}
					if (acegiMethodValues.length == 2 && acegiValue != null
							&& (acegiMethodValues[1].equalsIgnoreCase("false")
									|| acegiMethodValues[1].equalsIgnoreCase("true"))) {
						if (acegiMethodValues[1].equalsIgnoreCase("false")) {
							isObliged = 0;
						} else {
							isObliged = 1;
						}
						resourcesPutvalue(groupName, key, isObliged, acegiMethodValues[0], root);
						continue;
					}
					if (acegiMethodValues.length == 2 && acegiValue != null) {
						resourcesPutvalue(groupName, key, isObliged, acegiMethodValues[0], root);
						continue;
					}
					throw new Exception("权限配置错误=>>>>>" + key);
				}
			}
		}
		return root;
	}

	public static void setHave(HashMap<String, List<Authority>> resources, Map<String, List<Authority>> cach,
			String rolename) {
		for (String groupname : resources.keySet()) {
			List<Authority> tempList = resources.get(groupname);
			for (Authority security : tempList) {
				List<Authority> roles = cach.get(security.getValue());
				if (roles == null) {
					System.out.println(security.getValue());
					break;
				}
				for (Authority role : roles) {
					if (role.getRoleName().equalsIgnoreCase(rolename)) {
						security.setHaveSecurity(true);
						break;
					}
				}
			}
		}

	}

	private static void resourcesPutvalue(String groupName, String key, Short isObliged, String title,
			HashMap<String, List<Authority>> map) {
		List<Authority> mapItem = map.get(groupName);
		if (mapItem == null) {
			mapItem = new LinkedList<Authority>();
			map.put(groupName, mapItem);
		}
		Authority temp = new Authority();
		temp.setValue(key);
		temp.setTitle(title);
		temp.setObliged(isObliged);
		mapItem.add(temp);
	}

	private static void putValue(String key, String[] roles, Short isObliged, String title,
			HashMap<String, List<Authority>> map) {

		List<Authority> mapItem = map.get(key);
		if (mapItem == null) {
			mapItem = new LinkedList<Authority>();
			map.put(key, mapItem);
		}
		for (String role : roles) {
			Boolean isV = false;
			for (Authority security : mapItem) {
				if (security.getRoleName().equalsIgnoreCase(role)) {
					isV = true;
					break;
				}
			}
			if (isV) {
				continue;
			}
			Authority temp = new Authority();
			temp.setValue(key);
			temp.setRoleName(role);
			temp.setTitle(title);
			temp.setObliged(isObliged);
			mapItem.add(temp);
		}

	}

	/**
	 * 资源 与权限对应map 转换以请求路径为key的hash表，对应所有此路径访问权限的角色列表
	 * 
	 * @param list
	 * @return
	 */
	public static HashMap<String, List<Authority>> Transform(List<Authority> list) {
		HashMap<String, List<Authority>> root = new HashMap<String, List<Authority>>();
		for (Authority authority : list) {
			List<Authority> mapitem = root.get(authority.getValue());
			if (mapitem == null) {
				mapitem = new LinkedList<Authority>();
				root.put(authority.getValue(), mapitem);
			}
			mapitem.add(authority);
		}
		return root;
	}

	public static List<Authority> Transform(HashMap<String, List<Authority>> map) {
		LinkedList<Authority> root = new LinkedList<Authority>();
		for (String key : map.keySet()) {
			List<Authority> mapitem = map.get(key);
			for (Authority authority : mapitem) {
				root.add(authority);
			}
		}
		return root;
	}
}
